﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _1
{
    public class Bank
    {
        //银行管理多个账户
        private Dictionary<string, Account> accounts = new Dictionary<string, Account>();

        //索引器 通过账号来获取账户account,没有set 只能通过函数新增对象
        public Account this[string accountnumber]
        {
            get
            {
                if (accounts.ContainsKey(accountnumber))
                    return accounts[accountnumber];
                return null;
            }
        }

        //添加账户的方法
        public void addAccount(Account account)
        {
            if (!accounts.ContainsKey(account.accountNumber))
                accounts.Add(account.accountNumber, account);
        }
        //打印所有账户
        public void DisplayAccounts()
        {
            foreach (var account in accounts)
            {
                Console.WriteLine(account.Value.accountNumber);
            }
        }

    }
    public class Account
    {
        public string accountNumber { get; private set; }
        public decimal Balance { get; protected set; }
        public Account(string AccountNumber, decimal balance)
        {
            accountNumber = AccountNumber;
            Balance = balance;
        }

        //存款
        public void Deposit(decimal amount)
        {
            if (amount > 0)
            {
                Balance += amount;
                Console.WriteLine($"成功存入{amount:C},余额{Balance:C}");
            }
            else
            {
                Console.WriteLine("存款金额需要大于0");
            }

        }
        // 取款方法
        public virtual void Withdraw(decimal amount)
        {
            if (amount > 0 && amount <= Balance)
            {
                Balance -= amount;
                Console.WriteLine($"成功取出 {amount:C}。当前余额为 {Balance:C}");
            }
            else
            {
                Console.WriteLine("取款金额不合法或余额不足");
            }
        }
    }
    public class ATM
    {
        //取款机对应的银行
        private Bank bank;

        private Random random;

        //定义事件委托和事件
        public event EventHandler<BigMoneyArgs> BigMoneyFetched;


        public ATM(Bank bank)
        {
            this.bank = bank;
            random=new Random();
        }
        //存款
        public void Deposit(string accountNumber, decimal amount)
        {
            var account = bank[accountNumber];
            if (account != null)
            {
                account.Deposit(amount);
            }
            else
            {
                Console.WriteLine("账户不存在");
            }
        }

        //取款功能
        public virtual void Withdraw(string accountNumber, decimal amount)
        {
            var account = bank[accountNumber];
            if (account != null)
            {
                try
                {
                    if (random.NextDouble() < 0.3)
                    {
                        throw new BadCashException();
                    }
                    account.Withdraw(amount);
                    // 检查取款金额是否超过10000，如果是，激活事件
                    if (amount > 10000)
                    {
                        OnBigMoneyFetched(new BigMoneyArgs(accountNumber, amount));
                    }
                }
                catch (BadCashException e)
                {
                    Console.WriteLine($"取款失败：{e.Message}");
                }
            }
            else
            {
                Console.WriteLine("账户不存在");
            }
        }

        protected virtual void OnBigMoneyFetched(BigMoneyArgs args)
        {
            BigMoneyFetched?.Invoke(this, args);
        }
        public void CheckBalance(string AccountNumber)
        {
            var account = bank[AccountNumber];
            if (account != null)
            {
                Console.WriteLine($"账号: {account.accountNumber}, 余额: {account.Balance:C}");
            }
            else
            {
                Console.WriteLine("账户不存在");
            }
        }
    }
    public class CreditAccount : Account
    {
        //信用额度
        public decimal CreditLimit { get; private set; }
        public CreditAccount(string accountNumber, decimal initialBalance, decimal creditLimit)
            : base(accountNumber, initialBalance)
        {
            CreditLimit = creditLimit;
        }

        //重写取款发法 允许透支到信用额度
        public override void Withdraw(decimal amount)
        {
            if (amount > 0 && amount <= (Balance + CreditLimit))
            {
                Balance -= amount;
                Console.WriteLine($"成功取出 {amount:C}。当前余额为 {Balance:C}");
            }
            else
            {
                Console.WriteLine("取款金额不合法或余额不足");
            }

        }
        //新增查看可用额度的方法
        public decimal checkLimit()
        {
            return Balance + CreditLimit;
        }
    }
}
